<template>
  <div class="editable_tree" :style="{ 'min-height': loading ? '100vh' : '' }" v-loading="loading" element-loading-text="拼命加载中">
    <el-input placeholder="请输入关键字进行过滤" size="small" v-model="filterText" v-if="isShowFilter" :disabled="loading" class="editable_tree_filter_input" @keyup.enter.native="handleTreeFilterSearch">
      <div slot="suffix">
        <i class="iconfont icon-search" @click="handleTreeFilterSearch"></i>
      </div>
    </el-input>
    <div class="editable_tree_content" :style="{ height:heightAutoFlag?'77vh':'',overflow:heightAutoFlag?'auto':'' }">
      <el-tree v-if="!loading" :data="treeData" :indent="12" :node-key="nodeKey" :default-expand-all="isDefaultExpandAll" :default-expanded-keys="defaultExpandKeys" :expand-on-click-node="isExpandOnClickNode" :filter-node-method="handleFilterNode" :draggable="isDraggable" :allow-drag="handleAllDrag" :allow-drop="handleAllDrop" @node-click="handleNodeClick" highlight-current ref="treeRef" :class="['tree_ele',{'tree_ele_multi':isDragMultiNode}]" @node-drag-start="handleDragStart" @node-drag-end="handleDragEnd" :current-node-key="defaultSelectKey" :show-checkbox="isDragMultiNode" :check-strictly="isDragMultiNode" @node-expand="handleNodeExpand" @node-collapse="handleNodecollapse">
        <div class="slot_tree" slot-scope="{ node, data }">
          <!-- 编辑状态 -->
          <template v-if="node.isEdit">
            <el-input v-model="data.label" autofocus size="mini" :ref="`slotTreeInput${data[nodeKey]}`" @blur.stop="handleTreeNodeInput(node, data)" @keyup.enter.native="$event.target.blur"></el-input>
          </template>
          <!-- 非编辑状态 -->
          <template v-else-if="!node.isEdit && !data.isHide">
            <span class="tree_img" v-if="isShowIconImg">
              <!-- 如果 customIcon 为true，则用户需要绑定事件getTreeNodeIcon(data,callback)，返回节点图标，返回空则显示默认图标 -->
              <el-image :src="getTreeNodeCustomIcon(data)" fit="cover" @error="return true;" v-if="customIcon" class="tree_image" :title="getImgPropertyTypeUri(data)">
                <template slot="error">
                  <img src="./images/question.png" alt class="el-image__inner" :title="getImgPropertyTypeUri(data)" />
                </template>
              </el-image>
              <!-- 否则按默认的图标显示 -->
              <el-image v-else :src="data[propsData.isDirectory] ? folderIcon : nodeIcon" fit="cover" @error="return true;" class="tree_image" :title="getImgPropertyTypeUri(data)">
                <template slot="error">
                  <img src="./images/fold.png" alt class="el-image__inner" :title="getImgPropertyTypeUri(data)" />
                </template>
              </el-image>
            </span>
            <!-- 节点的label显示 -->
            <div class="tree_label" @mouseenter.stop="handleMouseEnter(data)" :title="getLabelTitle(data)">
              {{ data.label }}
              <!-- isShowCount为true，并且节点有count属性 -->
              <span class="tree_num" v-if="isShowCount && data.hasOwnProperty('count')">({{ data.count | tranNumber(2) }})</span>
              <span class="tree_num" v-if="isShowObjectAttrGroupCount" v-html="data.count"></span>
            </div>
            <!-- 工具栏 -->
            <span class="tree_btn">
              <!-- 节点按钮：新增（如果当前节点不是文件夹类型，就不允许新增） -->
              <template v-if="editable && data[propsData.isDirectory]">
                <el-tooltip content="创建节点" placement="top" v-if="isEditNode">
                  <i class="el-icon-plus tree_btn_add" @click.stop="handleAppendTreeNode(node, data, false)"></i>
                </el-tooltip>
                <el-tooltip content="创建文件夹" placement="top" v-if="isEditFolder">
                  <i class="el-icon-folder-add tree_btn_add" @click.stop="handleAppendTreeNode(node, data, true)"></i>
                </el-tooltip>
              </template>
              <!-- 拓展工具栏 -->
              <template v-if="isRename || isDelete || operateList.length > 0">
                <el-popover placement="bottom-end" width="100" trigger="hover" :append-to-body="false" popper-class="tree_content_popover" @show="popoverShowHandler(node,data)">
                  <ul class="popover_body">
                    <li @click.stop="handleRenameTreeItem(node, data)" v-if="isRename">
                      <img src="./images/edit.png" />
                      <span>{{ '重命名' }}</span>
                    </li>
                    <li @click.stop="handleRemoveTreeItem(node, data)" v-if="isDelete">
                      <img src="./images/delete.png" />
                      <span>{{ '删除' }}</span>
                    </li>
                    <li v-for="(oItem,oIndex) in operateList" :key="oIndex" @click.stop="handleTreeItemCall(node, oItem.callback)">
                      <el-image :src="oItem.imgSrc" fit="cover" @error="return true;">
                        <template slot="error">
                          <!-- <img src="@/assets/images/ontology/ptTypegroupType/icon_property.png" alt class="el-image__inner" /> -->
                        </template>
                      </el-image>
                      <span>{{oItem.label}}</span>
                    </li>
                  </ul>
                  <img src="./images/dot.png" alt slot="reference" class="popover_reference" />
                </el-popover>
              </template>
            </span>
          </template>
        </div>
      </el-tree>
      <div class="seeMore" v-if="isSeeMoreData" @click="seeMoreData">加载更多...</div>
    </div>
  </div>
</template>

<script>
// import { mapGetters, mapMutations } from 'vuex';
export default {
  created () {
    // 初始化props配置
    for (let key in this.propsData) {
      let value = this.props[key];
      if (value) {
        this.propsData[key] = value;
      }
    }
  },
  data () {
    return {
      loading: false,
      filterText: "",
      timer: null,                  // 检索词防抖定时器
      /** 默认prop配置 */
      propsData: {
        isDirectory: "isDirectory", //是否是文件夹属性
        children: "children" //children属性
      },
      addOrRename: "",              // 点击新增/重命名
      checkedKeys: [],
      isSeeMoreData: false,//是否存在加载更多
      seeMoreChildren: {},
      checkedKeysList: [],//树形多选选中的数据
    };
  },
  props: {
    heightAutoFlag: {
      // 判断是否固定高度
      type: Boolean,
      default: false
    },
    props: {
      // 树节点配置选项，默认值为propsData
      type: Object,
      default: () => { }
    },
    treeData: {
      // 树节点数据
      type: Array,
      default: () => []
    },
    nodeKey: {
      // 树节点唯一标识属性，默认：id
      type: String,
      default: "id"
    },
    defaultSelectKey: {
      // 初始选中节点的key, 默认空
      type: String,
      default: ''
    },
    isDefaultExpandAll: {
      // 是否默认展开所有子节点，默认：true
      type: Boolean,
      default: true
    },
    defaultExpandKeys: {
      // 默认展开的节点的keys的数组，默认：[]
      type: Array,
      default: () => []
    },
    isExpandOnClickNode: {
      // 是否点击节点展开子节点，默认：false
      type: Boolean,
      default: false
    },
    editable: {
      // 是否可编辑树，默认：false
      type: Boolean,
      default: false
    },
    isEditNode: {
      // 是否可创建节点，默认：true
      type: Boolean,
      default: true
    },
    isEditFolder: {
      // 是否可创建文件夹，默认：
      type: Boolean,
      default: true
    },
    isDraggable: {
      // 是否可拖拽节点，默认：false
      type: Boolean,
      default: false
    },
    isDragFolders: {
      // 是否可以拖拽文件夹，默认false
      type: Boolean,
      default: false
    },
    isDragMultiNode: {
      // 是否允许多选节点拖拽，默认false
      type: Boolean,
      default: false
    },
    onlyPutNext: {
      //是否只能放置在元素后面，默认false
      type: Boolean,
      default: false
    },
    isPutChild: {
      //是否能插入叶子节点里面，默认false
      type: Boolean,
      default: false
    },
    customIcon: {
      // 是否显示自定义图标，约定：回调函数中返回空字符串则按默认文件夹图标(folderIcon)或默认节点图标(nodeIcon)显示
      type: Boolean,
      default: false
    },
    folderIcon: {
      // 可展开节点图片，默认：文件夹图标
      type: String,
      default: require("./images/fold.png")
    },
    nodeIcon: {
      // 不可展开节点图片，默认：文件图标
      type: String,
      default: require("./images/question.png")
    },
    isShowCount: {
      // 是否显示节点数量统计，默认：true
      type: Boolean,
      default: true
    },
    isShowFilter: {
      // 是否显示树节点过滤，默认：false
      type: Boolean,
      default: false
    },
    customFilter: {
      // 是否自定义树节点过滤，默认：false
      type: Boolean,
      default: false
    },
    treeNodeTipField: {
      // 鼠标悬浮树图标上显示字段，默认：value
      type: String,
      default: "value"
    },
    treeLoading: {
      // 是否处于加载中，默认：true
      type: Boolean,
      default: true
    },
    isRename: {
      // 是否启用重命名树节点操作
      type: Boolean,
      default: false
    },
    isDelete: {
      // 是否启用删除树节点操作
      type: Boolean,
      default: false
    },
    operateList: {
      // 树节点操作按钮及回调方法，默认：[]
      /**
       * {
       * name:"share",             // 操作名称
       * label:"分享",             // 显示标签
       * imgSrc:"",                // 图标
       * callback:"handleShare"    // 操作回调方法，在父组件定义的方法
       * }
      */
      type: Array,
      default: () => []
    },
    // ellipsis: {
    //   // 限制显示文本个数，不传默认全部显示
    //   type: Number
    // },
    labelMaxLength: {
      // 限制显示文本个数，不传默认全部显示
      type: Number,
      default: 10
    },
    isShowObjectAttrGroupCount: { // 是否显示对象数/属性数/关系数
      type: Boolean,
      default: false,
    },
    isShowIconImg: { // 是否树形的图标
      type: Boolean,
      default: true,
    }
  },
  methods: {
    popoverShowHandler (node, data) {
      this.$emit('handlerPopoverShow', data)
    },
    // 当节点展开时触发
    handleNodeExpand (data, node) {
      if (this.heightAutoFlag) {
        if (data.childrenAll) {
          this.isSeeMoreData = true
          this.seeMoreChildren = data
        }
        if (data.id == "5cc808597026f162afd9216b") {
          let dataList = node.childNodes.filter(e => e.label == '未分组')
          let flag = dataList.some(e => e.expanded == true)
          if (flag) { this.isSeeMoreData = true }
        }
      }
    },
    // 当节点关闭
    handleNodecollapse (data, node) {
      if (this.heightAutoFlag) {
        if (data.childrenAll || data.id == "5cc808597026f162afd9216b") {
          this.isSeeMoreData = false
        }
      }
    },
    // 加载更多的数据
    seeMoreData () {
      let length = this.seeMoreChildren.children.length
      this.seeMoreChildren.children = this.seeMoreChildren.childrenAll.slice(0, length + 30)
    },
    // ...mapMutations(["setOeDragging", "setOeDragList"]),
    // 外部区域拖拽元素到树集合(叶子节点)上
    /**
     * 外部区域需绑定可拖拽属性及一个事件：
     * :draggable="true" 设置该元素可被拖拽
     * @dragstart="handleDragStart" 监听开始拖拽时事件，修改vuex拖拽状态为拖拽中及保存被拖拽元素数据
     * 
     * handleDragStart(event, item){
     *  this.setOeDragging();
     *  this.setOeDragList([
     *    {
     *      tid:"xxxxxxxxxxxxxxxxx",
     *      storageId:"xxxxx",
     *      objType:"xxxxx.xxxxx.xxxxx"
     *    },
     *    {
     *      tid:"xxxxxxxxxxxxxxxxx",
     *      storageId:"xxxxx",
     *      objType:"xxxxx.xxxxx.xxxxx"
     *    },
     *    {
     *      tid:"xxxxxxxxxxxxxxxxx",
     *      storageId:"xxxxx",
     *      objType:"xxxxx.xxxxx.xxxxx"
     *    }
     *  ]);
     * }
     */
    handleMouseEnter (data) {
      //   if ((data.children && data.children.length > 0) || (!this.getOeDragging && this.getOeDragList.length == 0)) return;
      //   data.count += this.getOeDragList.length;

      //   data.dragList = this.getOeDragList;
      //   this.$emit("handlerDragNodeAndList", data);
      //   console.log("拖拽结束", data, this.getOeDragList);

      //   // 拖拽结束修改vuex状态为未被拖拽中及清空被拖拽元素数据
      //   this.handleMouseOut();
    },
    // 去除在拖拽中的状态及清空被拖拽元素数据
    handleMouseOut () {
      this.setOeDragging(false);
      this.setOeDragList();
    },
    // 拖拽节点到外部区域
    /**
     * 外部区域需绑定两个事件：
     * @dragover.prevent 阻止默认行为设置元素为可拖放元素
     * @drop.prevent="handleDrop" 监听拖拽目标释放时获取被拖拽节点数据
     * 
     * handleDrop(event){
     *  let params = JSON.parse(event.dataTransfer.getData("params"));
     *   if(params.type == 'folderData') {
     *    console.log("被拖拽节点数据：",params);
     *  }
     * },
     */
    handleDragStart (node, event) {
      let dragData = [];
      if (!node.checked) {     // 当前拖拽节点未被选中，则选中当前节点即可
        this.checkedKeys = [node.data[this.nodeKey]];
        // this.$refs["treeRef"].setCheckedKeys(this.checkedKeys,true);
        this.$refs["treeRef"].setCurrentKey(this.checkedKeys[0]);
        dragData = [node.data];
      } else {
        dragData = this.$refs["treeRef"].getCheckedNodes(true, false);
      }
      event.dataTransfer.setData(
        "params",
        JSON.stringify({ type: "folderData", data: dragData })
      );
      // 关联图定制时间回调，关联图画布无法同时监听多个拖拽结束事件，传递出拖拽节点数组
      this.$emit("handleDragCallback", dragData, event);
    },
    /**
     * 添加树的节点名称
     * _node：节点信息
     * _data：输入信息
     */
    handleTreeNodeInput (_node, _data) {
      // 退出编辑状态
      this.$set(_node, "isEdit", false);
      // 处理_data的text为空的问题
      if (_data.label === "") {
        this.handleFilterEmptyTreeItem(_node, _data);
        return;
      }
      // 回调父组件的方法
      this.$emit("handleUpdateTreeData", { node: _node, type: this.addOrRename });
    },
    /** 添加树的节点（节点类型） */
    handleAppendTreeNode (node, data, isDirectory) {
      console.log('添加树的节点', node)
      if (!data.children) {
        this.$set(data, "children", []);
      }
      let id = new Date().getTime();
      let item = {
        id: "" + id,
        label: "",
        children: [],
        type: 'add', // 定义一个type,用于区分
      };
      item[this.propsData.isDirectory] = isDirectory;
      data.children.push(item);
      if (!node.expanded) {
        node.expanded = true;
      }
      this.addOrRename = "add";
      //添加后使新加的节点聚焦
      this.$nextTick(() => {
        this.handleEditTreeItem(node.childNodes[node.childNodes.length - 1], data.children[data.children.length - 1]);
      });
    },
    // 重命名节点
    handleRenameTreeItem (_node, _data) {
      this.addOrRename = "rename";
      this.handleEditTreeItem(_node, _data);
    },
    // 编辑树节点(重命名树节点)
    handleEditTreeItem (_node, _data) {
      console.log(_node, _data)
      console.log('this.nodeKey', this.nodeKey)
      // 节点开启编辑模式
      if (!_node.isEdit) {
        this.$set(_node, "isEdit", true);
        // 缓存旧值，如果接口调用失败后可以重置为旧值
        _data.oldLabel = _data.label;
      }
      // 输入框聚焦
      this.$nextTick(() => {
        if (this.$refs[`slotTreeInput${_data[this.nodeKey]}`]) {
          this.$refs[`slotTreeInput${_data[this.nodeKey]}`].$refs.input.focus();
        }
      });
    },
    /** 
     * 删除树节点
     * 父组件可以通过ref调用。一般用于：父组件新增节点接口调用失败时，将节点删除
     */
    removeTreeItem (treeNode) {
      this.$refs["treeRef"].remove(treeNode);
    },
    /**
     * 删除树节点，回调父组件
     */
    handleRemoveTreeItem (node, data) {
      let nodeType = data[this.propsData.isDirectory] ? '文件夹' : '节点';
      this.$confirm(`是否确定删除该${nodeType}？`, '信息', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: "error"
      }).then(() => {
        const parent = node.parent;
        const children = parent.data.children || parent.data;
        const index = children.findIndex(
          d => d[this.nodeKey] === data[this.nodeKey]
        );
        children.splice(index, 1);
        // 通知父组件删除节点调用接口
        this.$emit("handleDeleteTreeData", node);
      }).catch(() => { });
    },
    // 移除空节点
    handleFilterEmptyTreeItem (node, data) {
      const parent = node.parent;
      const children = parent.data.children || parent.data;
      const index = children.findIndex(
        d => d[this.nodeKey] === data[this.nodeKey]
      );
      children.splice(index, 1);
    },
    // 点击树节点-----传递node(里面包含data的数据)
    handleNodeClick (data, node) {
      if (!data.label) return;
      if (!this.isDragMultiNode) {     // 不允许多选节点，将当前选中节点传递出去
        this.$emit("handleNodeClick", data, node);
      } else {                         // 允许多选节点，将所选节点选中
        if (data[this.propsData.isDirectory]) return;
        if (event.ctrlKey) {
          if (this.checkedKeys.length) {
            let existItemIndex = this.checkedKeys.findIndex(f => f === data[this.nodeKey]);
            if (existItemIndex == -1) {
              this.checkedKeys.push(data[this.nodeKey]);
              this.checkedKeysList.push(data)
            } else {
              this.checkedKeys.splice(existItemIndex, 1);
              this.checkedKeysList.splice(existItemIndex, 1)
            }
          } else {
            this.checkedKeys = [data[this.nodeKey]];
            this.checkedKeysList = [data];
          }
        } else {
          this.checkedKeys = [data[this.nodeKey]];
          this.checkedKeysList = [data];
        }
        this.$refs["treeRef"].setCheckedKeys(this.checkedKeys, true);
        this.$emit("getCheckedKeysList", this.checkedKeysList)
      }

    },
    /**
     * 树节点被拖拽释放时触发
     * node：被拖拽的节点
     * intoNode：拖拽节点放置到哪个节点下
     * location：放的位置
     * event：拖拽事件
     */
    handleDragEnd (node, intoNode, location, event) {
      this.$emit("handleDragEnd", node, intoNode, location, event);
    },
    // 过滤树节点
    handleFilterNode (value, data, node) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    // 文件夹不允许拖拽
    handleAllDrag (node) {
      // return node.level !== 1;
      if (this.isDragFolders) {
        return true;
      } else {
        return !node.data[this.propsData.isDirectory] && node.isLeaf;
      }
    },
    handleAllDrop (draggingNode, dropNode, type) {
      if (this.onlyPutNext) {// 是否 只允许在元素后面放
        if (this.isPutChild) { //允许放里面或者后面
          return type === 'inner' || type === 'next'
        }
        return type === 'next'
      }
      if (!this.isPutChild && dropNode.isLeaf) {
        return type !== 'inner' // 不允许在子叶节点里放置节点
      } else {
        return true
      }
    },
    // 操作按钮点击事件-----调用父组件的功能函数
    handleTreeItemCall (node, method) {
      this.$parent[method](node);
    },
    // 获取节点自定义图标，父组件绑定事件 getTreeNodeIcon，参数为节点data数据、回调函数，返回图标，返回空，则显示默认图标
    getTreeNodeCustomIcon (data) {
      let imgSrc = "";
      this.$emit("getTreeNodeIcon", data, iconUrl => {
        if (iconUrl) {            // 返回不为空则显示该图标
          imgSrc = iconUrl;
        } else {                  // 返回为空，则显示默认图标
          if (data[this.propsData.isDirectory]) {
            imgSrc = this.folderIcon;
          } else {
            imgSrc = this.nodeIcon;
          }
        }
      });
      return imgSrc;
    },
    // 树搜索
    handleTreeFilterSearch () {
      if (!this.customFilter) {                 // 默认树节点过滤
        this.$refs.treeRef.filter(this.filterText);
      } else {                                  // 自定义搜索树节点过滤
        this.loading = true;
        this.$emit("customSearchTree", this.filterText);
      }
    }
  },
  watch: {
    treeLoading: {                             // 树加载变化
      immediate: true,
      handler (newVal, oldVal) {
        this.loading = newVal;
      }
    },
    treeData: {                                // 树数据变化，关闭loading
      handler (newVal, oldVal) {
        this.loading = false;
      },
      deep: true
    }
  },
  computed: {
    // ...mapGetters(["getOeDragging", "getOeDragList"]),
    getLabelTitle () {                              // 树节点超过一定字数，鼠标悬浮显示完整属性名称
      return function (data) {
        let title = "";
        if (data.label.length > this.labelMaxLength) {
          title = data.label;
          if (this.isShowCount && Object.prototype.hasOwnProperty.call(data, 'count')) {
            title += `(${data.count})`;
          }
        }
        return title;
      }
    },
    getImgPropertyTypeUri () {                       // 鼠标悬浮树节点图标，显示属性uri
      return function (data) {
        let title = "";
        if (Object.prototype.hasOwnProperty.call(this, 'treeNodeTipField')) {
          title = data[this.treeNodeTipField];
        }
        return title;
      }
    }
  }
};
</script>

<style lang="less" scoped>
@b-text-title: #4a4a4a; // 一级标题字体颜色
@b-main-light: #2ea9ed;
@b-assist-line: #e9e9e9;
@b-assist-lightbg: #f0f5fb;
@b-text-content: #878787;

.editable_tree {
  height: calc(100% + 70px);
  overflow: auto;
  position: relative;
  /deep/.editable_tree_filter_input {
    .el-input__suffix {
      cursor: pointer;
      .el-input__suffix-inner {
        .icon-search {
          position: relative;
          top: 11px;
        }
      }
    }
  }
  .tree_ele {
    color: @b-text-title;
    /deep/.el-tree-node {
      &:focus,
      &.is-current {
        > .el-tree-node__content {
          background-color: @b-assist-line !important;
          .slot_tree {
            color: @b-main-light !important;
          }
        }
      }
      .el-tree-node__content {
        height: 30px;
        line-height: 30px;
        &:hover {
          //   .bg(@b-assist-lightbg);
          .slot_tree {
            // color: @b-main-light;
            .tree_btn {
              display: flex;
            }
          }
        }
        .el-tree-node__expand-icon {
          color: @b-text-title;
          padding: 4px;
          &.is-leaf {
            visibility: hidden;
          }
        }
        .slot_tree {
          color: @b-text-content;
          font-size: 12px;
          display: flex;
          align-items: center;
          width: 100%;
          padding-right: 4px;
          .tree_image {
            width: 16px;
            height: 16px;
            border-radius: 50%;
            margin-right: 4px;
          }
          .tree_label {
            flex: 1;
            .tree_num {
              font-weight: normal;
            }
          }
          .tree_img {
            display: inline-block;
            height: 24px;
          }
          .tree_btn {
            // display: flex;
            display: none;
            align-items: center;
            > span {
              display: flex;
              align-items: center;
              margin-left: 5px;
            }
            .tree_btn_add {
              font-weight: 600;
              font-size: medium;
              color: @b-main-light;
              &:first-child {
                margin-right: 4px;
              }
            }
            .tree_content_popover {
              // min-width: 100px;
              padding: 4px 0;
              .popover_body {
                font-size: 13px;
                > li {
                  font-size: 13px;
                  display: flex;
                  align-items: center;
                  height: 28px;
                  cursor: pointer;
                  padding: 0 6px;
                  &:hover {
                    // .bg(@b-assist-line);
                    color: @b-main-light;
                  }
                  .el-image,
                  img {
                    width: 16px;
                    height: 16px;
                  }
                  span {
                    margin-left: 5px;
                  }
                }
              }
            }
          }
        }
      }
      .el-tree-node__children {
        .el-tree-node {
          &:focus {
            > .el-tree-node__content {
              .slot_tree {
                color: @b-main-light;
              }
            }
          }
          .el-tree-node__content {
            &:hover {
              .slot_tree {
                // color: @b-main-light;
              }
            }
          }
        }
      }
      .el-tree-node__content,
      .el-tree-node__children {
        .el-checkbox {
          display: none;
        }
      }
    }
    &.tree_ele_multi {
      /deep/.el-tree-node {
        &:focus,
        &.is-current {
          > .el-tree-node__content {
            background-color: unset !important;
            .slot_tree {
              color: @b-text-content !important;
            }
          }
        }
        &.is-checked {
          > .el-tree-node__content {
            background-color: @b-assist-line !important;
            .slot_tree {
              color: @b-main-light !important;
            }
          }
        }
      }
    }
  }
  .seeMore {
    text-align: center;
    color: #007ee5;
    font-size: 14px;
    cursor: pointer;
  }
}
</style>

<style lang="less">
.editable_tree {
  overflow: hidden;
  &.el-loading-parent--relative {
    .el-loading-mask {
      .el-loading-spinner {
        top: 150px;
      }
    }
  }
  // .editable_tree_content {
  //   height: 78vh;
  //   overflow: auto;
  // }
}
</style>
